using System;
using System.Collections;
using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
namespace BMC.ARSystem
{
	public abstract class DataExporter
	{
		[Guid("dd57e531-aa27-4b24-82e3-0ae47e076f97")]
		public class ExportDataBeginArgs
		{
			public readonly string FileName;
			public readonly string FormName;
			public readonly DateTime ExportTime;
			public readonly string AttachmentsFolder;
			public readonly int NumTotalRows;
			internal ExportDataBeginArgs(string filePath, string formName, DateTime exportTime, string attachmentsFolder, int numTotalRows)
			{
				this.FileName = filePath;
				this.FormName = formName;
				this.ExportTime = exportTime;
				this.AttachmentsFolder = attachmentsFolder;
				this.NumTotalRows = numTotalRows;
			}
		}
		[Guid("063d883d-6c3d-4859-aa06-e41a37a92790")]
		public class ExportRecordBeginArgs
		{
			public readonly uint RecordNumber;
			public EntryFieldValue Entry;
			public bool SkipRecord;
			public bool StopExport;
			internal ExportRecordBeginArgs(uint recordNumber, EntryFieldValue entry)
			{
				this.RecordNumber = recordNumber;
				this.Entry = entry;
				this.SkipRecord = (this.StopExport = false);
			}
		}
		[Guid("c0a53866-4611-48ee-bbb7-8321992dafb1")]
		public class ExportAttachmentValueEventArgs
		{
			public readonly uint RecordNumber;
			public readonly EntryFieldValue Entry;
			public readonly long FieldId;
			public readonly string AttachmentsFolder;
			public string AttachFileName;
			internal ExportAttachmentValueEventArgs(uint recordNumber, EntryFieldValue entry, uint fieldId, string attachmentsFolder, string attachFileName)
			{
				this.RecordNumber = recordNumber;
				this.Entry = entry;
				this.FieldId = (long)((ulong)fieldId);
				this.AttachmentsFolder = attachmentsFolder;
				this.AttachFileName = attachFileName;
			}
		}
		[Guid("8bc3ebe0-1eb2-4208-bbcc-b37ae374ccca")]
		public class ExportRecordEndArgs
		{
			public readonly uint RecordNumber;
			public EntryFieldValue Entry;
			public bool StopExport;
			internal ExportRecordEndArgs(uint recordNumber, EntryFieldValue entry)
			{
				this.RecordNumber = recordNumber;
				this.Entry = entry;
				this.StopExport = false;
			}
		}
		[Guid("f2ed59cd-c03b-46a9-8169-f7090e4a4a23")]
		public class ExportRecordFailedArgs
		{
			public readonly uint NumFailed;
			public readonly uint RecordNumber;
			public EntryFieldValue Entry;
			public bool StopExport;
			public readonly Exception FailureReason;
			internal ExportRecordFailedArgs(uint recordNumber, EntryFieldValue entry, uint numFailed, Exception failureReason)
			{
				this.RecordNumber = recordNumber;
				this.Entry = entry;
				this.NumFailed = numFailed;
				this.FailureReason = failureReason;
				this.StopExport = false;
			}
		}
		[Guid("ec30722f-5f85-4a5f-986f-895baadc13f6")]
		public class ExportDataEndArgs
		{
			public string FileName;
			public readonly uint NumRowsTotal;
			public readonly uint NumRowsExported;
			public readonly uint NumRowsFailed;
			public readonly uint NumRowsSkipped;
			public readonly bool ExportedAttachVal;
			internal ExportDataEndArgs(string fileName, uint numRowsTotal, uint numExported, uint numFailed, uint numSkipped, bool exportedAttachVal, string attachFolder)
			{
				this.FileName = fileName;
				this.NumRowsTotal = numRowsTotal;
				this.NumRowsExported = numExported;
				this.NumRowsFailed = numFailed;
				this.NumRowsSkipped = numSkipped;
				this.ExportedAttachVal = exportedAttachVal;
			}
		}
		[Guid("0f89e601-71a3-4604-8be7-54c2ca890381")]
		public delegate void ExportDataBeginEventHandler(DataExporter.ExportDataBeginArgs e);
		[Guid("cb672011-116c-4e84-853b-f7833bd600c8")]
		public delegate void ExportRecordBeginEventHandler(DataExporter.ExportRecordBeginArgs e);
		[Guid("5930f91a-0704-4d32-849d-c7329cc5f875")]
		public delegate void ExportAttachmentValueEventHandler(DataExporter.ExportAttachmentValueEventArgs e);
		[Guid("f5b65e60-8ba5-4190-bb9b-810843c0342a")]
		public delegate void ExportRecordEndEventHandler(DataExporter.ExportRecordEndArgs e);
		[Guid("ea48d5f8-7ab9-4406-92c6-19fc6ead0779")]
		public delegate void ExportRecordFailedEventHandler(DataExporter.ExportRecordFailedArgs e);
		[Guid("251c79ad-0354-4166-8893-1df7c0ec1060")]
		public delegate void ExportDataEndEventHandler(DataExporter.ExportDataEndArgs e);
		public static readonly string LABEL_STATUS_HISTORY_DEFAULT_LABEL = "Status-History";
		public event DataExporter.ExportDataBeginEventHandler ExportDataBeginEvent
		{
			[MethodImpl(32)]
			add
			{
				this.ExportDataBeginEvent = (DataExporter.ExportDataBeginEventHandler)Delegate.Combine(this.ExportDataBeginEvent, value);
			}
			[MethodImpl(32)]
			remove
			{
				this.ExportDataBeginEvent = (DataExporter.ExportDataBeginEventHandler)Delegate.Remove(this.ExportDataBeginEvent, value);
			}
		}
		public event DataExporter.ExportRecordBeginEventHandler ExportRecordBeginEvent
		{
			[MethodImpl(32)]
			add
			{
				this.ExportRecordBeginEvent = (DataExporter.ExportRecordBeginEventHandler)Delegate.Combine(this.ExportRecordBeginEvent, value);
			}
			[MethodImpl(32)]
			remove
			{
				this.ExportRecordBeginEvent = (DataExporter.ExportRecordBeginEventHandler)Delegate.Remove(this.ExportRecordBeginEvent, value);
			}
		}
		public event DataExporter.ExportAttachmentValueEventHandler ExportAttachmentValueEvent
		{
			[MethodImpl(32)]
			add
			{
				this.ExportAttachmentValueEvent = (DataExporter.ExportAttachmentValueEventHandler)Delegate.Combine(this.ExportAttachmentValueEvent, value);
			}
			[MethodImpl(32)]
			remove
			{
				this.ExportAttachmentValueEvent = (DataExporter.ExportAttachmentValueEventHandler)Delegate.Remove(this.ExportAttachmentValueEvent, value);
			}
		}
		public event DataExporter.ExportRecordEndEventHandler ExportRecordEndEvent
		{
			[MethodImpl(32)]
			add
			{
				this.ExportRecordEndEvent = (DataExporter.ExportRecordEndEventHandler)Delegate.Combine(this.ExportRecordEndEvent, value);
			}
			[MethodImpl(32)]
			remove
			{
				this.ExportRecordEndEvent = (DataExporter.ExportRecordEndEventHandler)Delegate.Remove(this.ExportRecordEndEvent, value);
			}
		}
		public event DataExporter.ExportRecordFailedEventHandler ExportRecordFailedEvent
		{
			[MethodImpl(32)]
			add
			{
				this.ExportRecordFailedEvent = (DataExporter.ExportRecordFailedEventHandler)Delegate.Combine(this.ExportRecordFailedEvent, value);
			}
			[MethodImpl(32)]
			remove
			{
				this.ExportRecordFailedEvent = (DataExporter.ExportRecordFailedEventHandler)Delegate.Remove(this.ExportRecordFailedEvent, value);
			}
		}
		public event DataExporter.ExportDataEndEventHandler ExportDataEndEvent
		{
			[MethodImpl(32)]
			add
			{
				this.ExportDataEndEvent = (DataExporter.ExportDataEndEventHandler)Delegate.Combine(this.ExportDataEndEvent, value);
			}
			[MethodImpl(32)]
			remove
			{
				this.ExportDataEndEvent = (DataExporter.ExportDataEndEventHandler)Delegate.Remove(this.ExportDataEndEvent, value);
			}
		}
		public DataExporter()
		{
		}
		internal void ExportData(string filePath, string formName, string qualification, bool isAppendMode, Encoding encoding, string vuiName, bool useLocale, Server server)
		{
			ArrayList fieldNames = new ArrayList();
			ArrayList listField = server.GetListField(formName, 1);
			listField.Sort();
			Hashtable fieldsMap = new Hashtable(listField.get_Count());
			this.GetFieldInfo(server, formName, listField, ref fieldNames, ref fieldsMap);
			object writer = this.CreateWriter(filePath, encoding, isAppendMode);
			this.WriteHeader(formName, server.ServerCharSet, fieldNames, fieldsMap, writer);
			DateTime now = DateTime.get_Now();
			string directoryName = Path.GetDirectoryName(filePath);
			string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(filePath);
			string text = string.Format("{0}_{1}", fileNameWithoutExtension, Util.GetARTimestamp(now));
			string text2 = Path.Combine(directoryName, text);
			EntryListFieldList entryListFieldList = new EntryListFieldList();
			entryListFieldList.AddField(1, 1, " ");
			EntryListFieldList arg_B4_3 = entryListFieldList;
			uint arg_B4_4 = 0u;
			uint arg_B4_5 = 999999999u;
			int num = 0;
			ArrayList listEntry = server.GetListEntry(formName, qualification, arg_B4_3, arg_B4_4, arg_B4_5, out num, null, vuiName, useLocale);
			if (this.ExportDataBeginEvent != null)
			{
				DataExporter.ExportDataBeginArgs e = new DataExporter.ExportDataBeginArgs(filePath, formName, now, text2, listEntry.get_Count());
				this.ExportDataBeginEvent(e);
			}
			ArrayList arrayList = new ArrayList(listEntry.get_Count());
			IEnumerator enumerator = listEntry.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					EntryDescription entryDescription = (EntryDescription)enumerator.get_Current();
					arrayList.Add(entryDescription.EntryId);
				}
			}
			finally
			{
				IDisposable disposable = enumerator as IDisposable;
				if (disposable != null)
				{
					disposable.Dispose();
				}
			}
			int num2 = arrayList.get_Count() / 1000 + ((arrayList.get_Count() % 1000 == 0) ? 0 : 1);
			bool flag = false;
			uint numExported = 0u;
			uint numFailed = 0u;
			uint numSkipped = 0u;
			bool exportedAttachVal = false;
			int num3 = 0;
			for (int i = 0; i < num2; i++)
			{
				int num4 = (i + 1 == num2) ? (arrayList.get_Count() - i * 1000) : 1000;
				string[] array = new string[num4];
				Array.Copy(arrayList.ToArray(typeof(string)), i * 1000, array, 0, num4);
				ArrayList entryIds = new ArrayList(array);
				ArrayList multipleEntries = server.GetMultipleEntries(formName, entryIds, (uint[])listField.ToArray(typeof(uint)));
				enumerator = multipleEntries.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						EntryFieldValue entry = (EntryFieldValue)enumerator.get_Current();
						if (this.ExportEntry(server, writer, formName, fieldNames, fieldsMap, entry, text2, text, ref exportedAttachVal, ref num3, ref numExported, ref numFailed, ref numSkipped) == -2)
						{
							flag = true;
							break;
						}
					}
				}
				finally
				{
					IDisposable disposable = enumerator as IDisposable;
					if (disposable != null)
					{
						disposable.Dispose();
					}
				}
				if (flag)
				{
					break;
				}
			}
			this.WriteFooter(writer);
			this.CloseWriter(writer);
			if (this.ExportDataEndEvent != null)
			{
				DataExporter.ExportDataEndArgs e2 = new DataExporter.ExportDataEndArgs(filePath, (uint)listEntry.get_Count(), numExported, numFailed, numSkipped, exportedAttachVal, text2);
				this.ExportDataEndEvent(e2);
			}
		}
		private int ExportEntry(Server server, object writer, string formName, ArrayList fieldNames, Hashtable fieldsMap, EntryFieldValue entry, string attachValAbsFolder, string attachValRelFolder, ref bool hasAttachVal, ref int attachValCount, ref uint numExported, ref uint numFailed, ref uint numSkipped)
		{
			if (this.ExportRecordBeginEvent != null)
			{
				DataExporter.ExportRecordBeginArgs exportRecordBeginArgs = new DataExporter.ExportRecordBeginArgs(numExported, entry);
				this.ExportRecordBeginEvent(exportRecordBeginArgs);
				if (exportRecordBeginArgs.SkipRecord)
				{
					numSkipped += 1u;
					return -1;
				}
				if (exportRecordBeginArgs.StopExport)
				{
					return -2;
				}
			}
			try
			{
				this.WriteRecord(server, writer, formName, fieldNames, fieldsMap, entry, attachValAbsFolder, attachValRelFolder, ref hasAttachVal, ref attachValCount, ref numExported, ref numFailed, ref numSkipped);
				numExported += 1u;
				if (this.ExportRecordEndEvent != null)
				{
					DataExporter.ExportRecordEndArgs exportRecordEndArgs = new DataExporter.ExportRecordEndArgs(numExported, entry);
					this.ExportRecordEndEvent(exportRecordEndArgs);
					if (exportRecordEndArgs.StopExport)
					{
						int result = -2;
						return result;
					}
				}
			}
			catch (Exception failureReason)
			{
				numFailed += 1u;
				if (this.ExportRecordFailedEvent != null)
				{
					DataExporter.ExportRecordFailedArgs exportRecordFailedArgs = new DataExporter.ExportRecordFailedArgs(numExported - 1u, entry, numFailed, failureReason);
					this.ExportRecordFailedEvent(exportRecordFailedArgs);
					if (exportRecordFailedArgs.StopExport)
					{
						int result = -2;
						return result;
					}
				}
			}
			return 0;
		}
		protected abstract object CreateWriter(string filePath, Encoding encoding, bool isAppendMode);
		protected abstract void CloseWriter(object writer);
		protected abstract void WriteHeader(string formName, string serverCharSet, ArrayList fieldNames, Hashtable fieldsMap, object writer);
		protected abstract void WriteFooter(object writer);
		protected abstract void WriteRecord(Server server, object writer, string formName, ArrayList fieldNames, Hashtable fieldsMap, EntryFieldValue entry, string attachValAbsFolder, string attachValRelFolder, ref bool hasAttachVal, ref int attachValCount, ref uint numExported, ref uint numFailed, ref uint numSkipped);
		private void GetFieldInfo(Server server, string formName, ArrayList dataFieldIds, ref ArrayList fieldNames, ref Hashtable fieldsMap)
		{
			IEnumerator enumerator = dataFieldIds.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					uint num = (uint)enumerator.get_Current();
					try
					{
						Field field = server.GetField(formName, num);
						if (field.FieldOption != 4u)
						{
							fieldNames.Add(field.Name);
							fieldsMap.Add(field.Name, field);
						}
					}
					catch (Exception var_2_48)
					{
						dataFieldIds.Remove(num);
					}
				}
			}
			finally
			{
				IDisposable disposable = enumerator as IDisposable;
				if (disposable != null)
				{
					disposable.Dispose();
				}
			}
			fieldNames.Sort();
		}
		protected virtual void OnExportAttachmentValueEvent(DataExporter.ExportAttachmentValueEventArgs e)
		{
			if (this.ExportAttachmentValueEvent != null)
			{
				this.ExportAttachmentValueEvent(e);
			}
		}
	}
}
